
Imports std
Imports System.IO

Module matchline

    Public Sub prepareIndexColumn(ByRef input As String, ByRef indexColumn As vector(Of Int32))
        Dim i As Int32
        Dim parts As vector(Of String) = Nothing
        If indexColumn Is Nothing Then
            indexColumn = New vector(Of Int32)
        Else
            indexColumn.clear()
        End If
        strsepar(input, character.comma + character.semicolon + character.sheffer + character.tab + character.blank _
                        + character.fullStop + character.leftSlash + character.rightSlash, parts)
        For i = 0 To parts.size() - 1
            indexColumn.push_back(Convert.ToInt32(parts(i)))
        Next
    End Sub

    Sub Main(ByVal args() As String)
        On Error Resume Next
        Dim reader As TextReader = Nothing
        Dim writer As TextWriter = Nothing
        Dim unmatchWriter As TextWriter = Nothing
        Dim input As String = Nothing
        Dim parts As vector(Of String) = Nothing
        Dim index As map(Of String, list(Of vector(Of String))) = Nothing
        Dim indexColumn As vector(Of Int32) = Nothing
        Dim i As Int32
        Dim work As map(Of String, list(Of vector(Of String))).iterator = Nothing
        Dim it As list(Of vector(Of String)).iterator = Nothing

        If args.Length <> 5 AndAlso args.Length <> 6 Then
            raiseError("argument count error, input1 column1,column2,... input2 column1,column2... match_output [unmatch_output], " + _
                        "if input/output is '/-', use console", errorHandle.errorType.critical)
        Else
            If args(4) = "/-" Then
                writer = Console.Out
            Else
                writer = New StreamWriter(New FileStream(args(4), FileMode.Create, FileAccess.Write, FileShare.Read))
            End If
            assert(Not writer Is Nothing, "file no found, " + args(4))

            If args.Length = 6 Then
                If args(5) = "/-" Then
                    unmatchWriter = Console.Out
                Else
                    unmatchWriter = New StreamWriter(New FileStream(args(5), FileMode.Create, FileAccess.Write, FileShare.Read))
                End If
                assert(Not unmatchWriter Is Nothing, "file no found, " + args(5))
            End If

            prepareIndexColumn(args(1), indexColumn)
            If args(0) = "/-" Then
                reader = Console.In
            Else
                reader = New StreamReader(New FileStream(args(0), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            End If
            assert(Not reader Is Nothing, "file no found, " + args(0))

            index = New map(Of String, list(Of vector(Of String)))
            input = reader.ReadLine
            While Not input Is Nothing
                strsepar(input, character.tab, parts)
                input = Nothing
                For i = 0 To indexColumn.size() - 1
                    If indexColumn(i) < parts.size() AndAlso _
                        indexColumn(i) >= 0 Then
                        input += parts(indexColumn(i)) + character.tab
                    End If
                Next
                index(input).push_back(parts)
                input = reader.ReadLine
            End While
            closestream(reader)

            prepareIndexColumn(args(3), indexColumn)
            If args(2) = "/-" Then
                reader = Console.In
            Else
                reader = New StreamReader(New FileStream(args(2), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            End If
            assert(Not reader Is Nothing, "file no found, " + args(2))
            input = reader.ReadLine
            While Not input Is Nothing
                strsepar(input, character.tab, parts)
                input = defaultValue.emptyString
                For i = 0 To indexColumn.size() - 1
                    If indexColumn(i) < parts.size() AndAlso _
                        indexColumn(i) >= 0 Then
                        input += parts(indexColumn(i)) + character.tab
                    End If
                Next
                work = index.find(input)
                If work <> index.end() Then
                    it = (+work).second.begin()
                    While it <> (+work).second.end()
                        writer.Write(parts.ToString())
                        writer.Write(character.tab)
                        writer.WriteLine((+it).ToString())
                        it += 1
                    End While
                ElseIf Not unmatchWriter Is Nothing Then
                    unmatchWriter.WriteLine(parts.ToString())
                End If
                input = reader.ReadLine
            End While
            closestream(reader)

            closestream(writer)
            closestream(unmatchWriter)
        End If
    End Sub

End Module
